package com.android.monee.binding.observer;

import com.android.monee.binding.Field;

public class ObserverImpl<S, T, V> implements Observer<S, T, V>{

	private Field<S, V> sourceField;
	private T target;
	private Field<T, V> targetField;
	
	public ObserverImpl(Field<S, V> sourceField, T target, Field<T, V> targetField){
		this.sourceField = sourceField;
		this.target = target;
		this.targetField = targetField;
	}
	
	@Override
	public void updateTarget(S source) {
		if(isUpToDate(source))
			updateTarget(this.target, sourceField.get(source));
	}

	@Override
	public void updateTarget(T target, V newVal) {
		defaultUpdateTarget(target, newVal);
	}

	public void defaultUpdateTarget(T target, V newVal) {
		targetField.set(target, newVal);
	}
	
	@Override
	public Field<S, V> getSourceField(){
		return this.sourceField;
	}
	
	public boolean isUpToDate (S source){
		V sourceVal = sourceField.get(source);
		V targetVal = targetField.get(target);
		return (sourceVal == null && targetVal != null) ||
				(sourceVal != null && targetVal == null) ||
				(sourceVal != null && targetVal != null && !sourceVal.equals(targetVal));
	}
	
//	@Override
//	public void setSourceField(Field<S, V> field) {
//		this.sourceField = field;
//	}
//
//	@Override
//	public void setTargetField(Field<T, V> field) {
//		this.targetField = field;		
//	}
//
//	@Override
//	public void setTarget(T target) {
//		this.target = target;
//	}

//	private Field<T, U> modelField;
//	private V view;
//	private Vf viewField;
//	
//	public ObserverImpl2(V view, Vf viewField, Field<T, U> modelField){
//		this.modelField = modelField;
//		this.view = view;
//		this.viewField = viewField;
//	}
//	
//	@Override
//	public Field<T, U> getModelField() {
//		return this.modelField;
//	}
//	
//	@Override
//	public void update(T o, U newVal) {
//		this.viewField.set(view, newVal);
//	}
}
